#pragma once

class CHelpMenu : public CMessageMap
{
public:
    BEGIN_MSG_MAP(CHelpMenu)
        //ALT_MSG_MAP(1)
        COMMAND_ID_HANDLER(ID_HELP_ABOUT, OnHelpAbout)
    END_MSG_MAP()

public:
    LRESULT OnHelpAbout(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
    {
        MessageBox(nullptr, _T("About"), _T("Help"), MB_OK);
        return 0;
    }
};

class CEditMenu : public CMessageMap
{
public:
    BEGIN_MSG_MAP(CEditMenu)
        ALT_MSG_MAP(1)
        COMMAND_ID_HANDLER(ID_EDIT_COPY, OnEditCopy)
        COMMAND_ID_HANDLER(ID_EDIT_PASTE, OnEditPaste)
    END_MSG_MAP()

public:
    LRESULT OnEditCopy(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
    {
        MessageBox(nullptr, _T("Copy"), _T("Edit"), MB_OK);
        return 0;
    }

    LRESULT OnEditPaste(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
    {
        MessageBox(nullptr, _T("Paste"), _T("Edit"), MB_OK);
        return 0;
    }
};


template <class _T>
class CFileMenu : public CDynamicChain
{
    _T* m_lpWnd;

public:
    CFileMenu() { }
    CFileMenu(_T* lpWnd) : m_lpWnd(lpWnd) { }
    virtual ~CFileMenu() { }

public:
    BEGIN_MSG_MAP(CFileMenu)
        ALT_MSG_MAP(1)
        COMMAND_ID_HANDLER(ID_FILE_OPEN, OnFileOpen)
        COMMAND_ID_HANDLER(ID_FILE_EXIT, OnFileExit)
        CHAIN_MSG_MAP_DYNAMIC(1)
        CHAIN_MSG_MAP_DYNAMIC(2)

        ALT_MSG_MAP(2)
        COMMAND_ID_HANDLER(ID_FILE_OPEN, OnFileOpen2)
        COMMAND_ID_HANDLER(ID_FILE_EXIT, OnFileExit)

    //
    //  {
    //      if (CDynamicChain::CallChain(dynaChainID, hWnd, uMsg, wParam, lParam, lResult))
    //          return TRUE;
    //  }
    //

        CHAIN_MSG_MAP_DYNAMIC(1)
        CHAIN_MSG_MAP_DYNAMIC(2)
    END_MSG_MAP()

    LRESULT OnFileOpen(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
    {
        MessageBox(nullptr, _T("FileOpen"), _T("File"), MB_OK);
        return 0;
    }

    LRESULT OnFileOpen2(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
    {
        MessageBox(nullptr, _T("FileOpen2"), _T("File"), MB_OK);
        return 0;
    }

    LRESULT OnFileExit(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
    {
        m_lpWnd->DestroyWindow();
        return 0;
    }
};

class CWinTest3 : public CWindowImpl<CWinTest3>
{
    CFileMenu<CWinTest3> m_FileMenu;
    CEditMenu m_EditMenu;
    CHelpMenu m_HelpMenu;

public:
    CWinTest3() : m_FileMenu(this)
    {
        m_FileMenu.SetChainEntry(1, &m_EditMenu, 1);
        m_FileMenu.SetChainEntry(2, &m_HelpMenu, 0);
    }
    virtual ~CWinTest3() { }

public:
    BEGIN_MSG_MAP(CWinTest3)
        MESSAGE_HANDLER(WM_DESTROY, OnDestroyHandler)
        CHAIN_MSG_MAP_ALT_MEMBER(m_FileMenu, 2)
    END_MSG_MAP()

protected:
    LRESULT OnDestroyHandler(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
    {
        PostQuitMessage(0);
        return TRUE;
    }
};
